/**
 * 
 */
package zeroj.web.validator;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import zeroj.web.validator.annotations.IsDomain;
import zeroj.web.validator.annotations.IsEmail;
import zeroj.web.validator.annotations.IsInteger;
import zeroj.web.validator.annotations.IsNumber;
import zeroj.web.validator.annotations.IsRegex;
import zeroj.web.validator.annotations.IsString;
import zeroj.web.validator.impl.DomainValidator;
import zeroj.web.validator.impl.EmailValidator;
import zeroj.web.validator.impl.IntegerValidator;
import zeroj.web.validator.impl.NumberValidator;
import zeroj.web.validator.impl.RegexValidator;
import zeroj.web.validator.impl.StringValidator;

/**
 * @author LYL(lylsir at gmail dot com)
 *
 */
public final class ValidatorHelper {

	
	public static List<Validate> parseValidates(Class<?> clz) {
		
		List<Validate> validates = new ArrayList<Validate>();
		parseValidators(validates, null, clz);
		return validates;
	}
	
	private static void parseValidators(List<Validate> validates, String baseName, Class<?> clz) {
		
		for(Field filed : clz.getFields())
			parseFieldValidators(validates, null, filed);
		for(Method method : clz.getMethods())
			parseMethodValidators(validates, null, method);
	}
	
	private static void parseFieldValidators(List<Validate> validates, String baseName, Field field) {
		
		String name = field.getName();
		if(baseName != null)
			name = baseName + "." + name;
		Field[] fields = field.getClass().getFields();
		if(fields.length > 0) {
			for(Field f : fields) {
				parseValidators(validates, name, f.getClass());
			}
		} else {
			List<IValidator> validators = getValidators(field.getAnnotations());
			if(validators.size() == 0)
				return;
			validates.add(new Validate(name, validators));
		}
	}
	
	private static void parseMethodValidators(List<Validate> validates, String baseName, Method method) {
		
		List<IValidator> validators = getValidators(method.getAnnotations());
		if(validators.size() == 0)
			return;
		Character c = Character.toLowerCase(method.getName().charAt(3));
		String name = c + method.getName().substring(4);
		if(baseName != null)
			name = baseName + "." + name;
		validates.add(new Validate(name, validators));
	}
	
	private static List<IValidator> getValidators(Annotation[] annotations) {
		
		List<IValidator> validators = new ArrayList<IValidator>();
		for(Annotation anno : annotations) {
			
			Class<?> clz = anno.getClass();
			if(IsDomain.class == clz)
				validators.add(DomainValidator.getInstance());
			else if(IsEmail.class == clz) 
				validators.add(EmailValidator.getInstance());
			else if(IsInteger.class == clz)
				validators.add(new IntegerValidator(((IsInteger)anno).min(), ((IsInteger)anno).max()));
			else if(IsNumber.class == clz) 
				validators.add(NumberValidator.getInstance());
			else if(IsRegex.class == clz) 
				validators.add(new RegexValidator(((IsRegex)anno).pattern()));
			else if(IsString.class == clz) {
				IsString isString = (IsString)anno;
				validators.add(new StringValidator(isString.minLen(), isString.maxLen()));
			}
		}
		return validators;
	}
}
